//? 参数可能包含函数、正则、日期、ES6新对象  与浅拷贝的不同在于需要递归至最深处 且需要防止递归引用

const _deepClone = (target, map = new WeakMap()) => {

    if (typeof target === 'object' && target !== null) {
        const cons = target.constructor
        //? 不是对象和数组
        if (/^(Function|RegExp|Date|Map|Set)$/i.test(cons.name)) return target

        const deepCloneObj = Array.isArray(target) ? [] : {}
        //? map标记每一个出现过的属性，避免循环引用
        if (map.get(target)) {
            return map.get(target)
        }
        map.set(target, deepCloneObj)
        for (let prop in target) {
            if (target.hasOwnProperty(prop)) {
                deepCloneObj[prop] = _deepClone(target[prop],map)
            }
        }
        return deepCloneObj
    }
    else {
        return target
    }
}

//? 存在循环引用的对象
const test2 = {
    a: 'Hello',
    b: {
        c: 'World',
    },
};
test2.b.d = test2;
let result = _deepClone(test2)
//? 测试修改原对象会不会影响深拷贝后的对象
test2.a = '3'
//? 事实证明是不会的啦 其循环引用里也没有被修改
console.log('res',result.b.d)
